using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;

namespace Xfinity
{
    /// <summary>
    /// Holds a camera.
    /// </summary>
    public interface ICameraHolder
    {
        /// <summary>
        /// The active camera.
        /// </summary>
        ICamera ActiveCamera { get;set;}
    }
    /// <summary>
    /// Defines an interface for a camera.
    /// </summary>
    public interface ICamera : IWorldViewProjection
    {
        /// <summary>
        /// Gets or sets the near view plane.
        /// </summary>
        float NearPlane {get;set;}
        /// <summary>
        /// Gets or sets the far view plane.
        /// </summary>
        float FarPlane {get;set;}
        /// <summary>
        /// Gets or sets the aspect ratio.
        /// </summary>
        /// <value>The aspect ratio.</value>
        float AspectRatio { get; set;}
        /// <summary>
        /// Gets or sets the up vector.
        /// </summary>
        /// <value>The up vector.</value>
        Vector3 Up { get; set;}
        /// <summary>
        /// Gets or sets the position.
        /// </summary>
        /// <value>The position.</value>
        Vector3 Position { get;set;}
        /// <summary>
        /// Gets or sets the target.
        /// </summary>
        /// <value>The target.</value>
        Vector3 Target { get;set;}
        /// <summary>
        /// Gets or sets the target direction.
        /// </summary>
        /// <value>The target direction.</value>
        Vector3 TargetDirection { get;set;}
        /// <summary>
        /// Make the camera look at a specified position.
        /// </summary>
        /// <param name="point">Where to look at.</param>
        void LookAt(Vector3 point);
        /// <summary>
        /// Move to a position in world coordinates, and look at a target in world coordinates.
        /// </summary>
        /// <param name="position">The absolute position.</param>
        /// <param name="target">The absolute target.</param>
        void MoveAndRotateAbsolute(Vector3 position, Vector3 target);
        /// <summary>
        /// Move and rotate the camera.
        /// </summary>
        /// <param name="positionOffset">The relative movement.</param>
        /// <param name="targetOffset">The relative rotation.</param>
        void MoveAndRotate(Vector3 positionOffset, Vector3 targetOffset);
        /// <summary>
        /// Rotates the pitch angle.
        /// </summary>
        /// <example>RotatePitch(MathHelper.ToRadians(90f));</example>
        /// <param name="angle">The angle to rotate, in radians</param>
        void RotatePitch(float pitch);
        /// <summary>
        /// Rotates the roll angle.
        /// </summary>
        /// <param name="angle">The angle to rotate, in radians</param>
        void RotateRoll(float roll);
        /// <summary>
        /// Rotates the yaw angle.
        /// </summary>
        /// <param name="angle">The angle to rotate, in radians</param>
        void RotateYaw(float yaw);
        /// <summary>
        /// Zoom in and out.
        /// </summary>
        /// <param name="fieldOfView">The field of view to zoom to, in half-radians. For a 90 degree FOV, send in MathHelper.ToRadians(45).</param>
        void Zoom(float fieldOfView);

    }
    /// <summary>
    /// Defines an interface for an object that has a renderable effect.
    /// </summary>
    public interface IRenderable : IWorldViewProjection, IDrawable
    {
        /// <summary>
        /// The effect.
        /// </summary>
        Effect Effect { get;set;}
        /// <summary>
        /// The parameters.
        /// </summary>
        EffectParameterCollection Parameters { get;}
    }
    /// <summary>
    /// Defines an interface for an object that has World, View, and Projection matrices.
    /// </summary>
    public interface IWorldViewProjection
    {
        /// <summary>
        /// The world transform.
        /// </summary>
        Matrix World { get; set;}
        /// <summary>
        /// The view transform.
        /// </summary>
        Matrix View { get; set;}
        /// <summary>
        /// The projection transform.
        /// </summary>
        Matrix Projection { get; set;}
    }
}